package com.kehutong.contact.service;

import com.kehutong.common.DoveClient;
import com.kehutong.common.entity.Root;
import com.kehutong.common.util.SnowflakeIdUtils;
import com.kehutong.common.util.Token;
import com.kehutong.contact.entity.Resident;
import com.kehutong.contact.entity.ResidentHouse;
import com.kehutong.contact.entity.ResidentHouseBindApply;
import com.kehutong.contact.enums.BindType;
import com.kehutong.contact.enums.HouseType;
import com.kehutong.contact.enums.ResidentType;
import com.kehutong.contact.service.impl.ResidentServiceImpl;
import org.coraframework.inject.Inject;
import org.coraframework.json.JSON;
import org.coraframework.json.JSONArray;
import org.coraframework.json.JSONObject;
import org.coraframework.logger.Logger;
import org.coraframework.logger.LoggerFactory;
import org.coraframework.mvc.http.ReqMapping;
import org.coraframework.mvc.http.result.Result;
import org.coraframework.mvc.webservice.WebService;
import org.coraframework.orm.Pool;
import org.coraframework.orm.jdbc.JdbcSession;
import org.coraframework.orm.jdbc.execute.entity.FindArray;
import org.coraframework.util.EnumUtil;
import org.coraframework.util.Objects;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * 住户资产服务类
 *
 * @author: liukunlong
 * @date: 2021-05-14 17:05
 */
@WebService("/crm/resident/house/service")
public class ResidentAssetsService {
    static final Logger logger = LoggerFactory.getLogger(ResidentAssetsService.class);

    @Inject
    private JdbcSession jdbcSession;

    @Inject
    private DoveClient doveClient;

    @Inject
    private ResidentServiceImpl residentService;

    public List<ResidentHouse> getResidentHouseList(JSONObject condition) {
        FindArray<ResidentHouse> find = jdbcSession.findArray(ResidentHouse.class)
                .eq(condition, "houseNo", "type", "residentNo")
                .in(condition, "bindType")
                .eq("deleted", false);
        return find.exe();
    }

    public List<ResidentHouse> getResidentHouseList(String houseNo, String type, List<String> bindType) {
        JSONObject condition = new JSONObject();
        condition.put("houseNo", houseNo);
        condition.put("type", type);
        condition.put("bindType", JSONArray.parseArray(JSON.toJSONString(bindType)));
        return getResidentHouseList(condition);
    }

    public List<ResidentHouse> getResidentHouseList(String houseNo, String type, List<String> bindType, String residentNo) {
        JSONObject condition = new JSONObject();
        condition.put("houseNo", houseNo);
        condition.put("type", type);
        condition.put("bindType", JSONArray.parseArray(JSON.toJSONString(bindType)));
        condition.put("residentNo", residentNo);
        return getResidentHouseList(condition);
    }

    public List<ResidentHouse> getResidentHouseList(String houseNo, String type, String bindType) {
        JSONObject condition = new JSONObject();
        JSONArray bindTypeList = new JSONArray();
        bindTypeList.add(bindType);
        condition.put("houseNo", houseNo);
        condition.put("type", type);
        condition.put("bindType", JSONArray.parseArray(JSON.toJSONString(bindTypeList)));
        return getResidentHouseList(condition);
    }

    /**
     * 根据房屋编号获取房屋绑定的业主信息
     *
     * @param houseNo 房屋编号
     * @return 房屋绑定的业主信息
     */
    @ReqMapping("/getHouseOwner")
    public ResidentHouse getHouseOwner(String houseNo) {
        if (Objects.isEmpty(houseNo)) {
            return null;
        }
        JSONObject condition = new JSONObject();
        JSONArray bindType = new JSONArray();
        bindType.add(BindType.NO_BIND.getId());
        bindType.add(BindType.BIND.getId());
        condition.put("houseNo", houseNo);
        condition.put("type", ResidentType.OWNER.getId());
        condition.put("bindType", bindType);
        List<ResidentHouse> residentHouseList = getResidentHouseList(condition);
        if (Objects.isEmpty(residentHouseList)) {
            return null;
        }
        return residentHouseList.get(0);
    }

    public String getFullHouseName(ResidentHouse residentHouse) {
        StringBuilder sb = new StringBuilder();
        String buildName = Objects.isEmpty(residentHouse.getBuildName()) ? "" : residentHouse.getBuildName();
        String unitName = Objects.isEmpty(residentHouse.getUnitName()) ? "" : residentHouse.getUnitName();
        String floorName = Objects.isEmpty(residentHouse.getFloorName()) ? "" : residentHouse.getFloorName();
        sb.append(residentHouse.getCommunityName()).append(">").append(buildName).append(unitName).append(">").append(floorName).append(residentHouse.getHouseName());
        return sb.toString();
    }


    /**
     * 构建住户房屋对象
     *
     * @param resident 住户信息
     * @param house    房屋信息
     * @return 住户房屋对象
     */
    public ResidentHouse buildResidentHouse(Resident resident, JSONObject house) {
        ResidentHouse residentHouse = Pool.newInstance(ResidentHouse.class);

        residentHouse.setRealname(resident.getRealname());

        residentHouse.setMobile(resident.getMobile());

        residentHouse.setAvatar(resident.getAvatar());

        residentHouse.setCompanyNo(resident.getCompanyNo());
        //设置绑定状态
        residentHouse.setBindType(BindType.NO_BIND);
        //住户编号编号
        residentHouse.setResidentNo(resident.getId());
        //小区编号
        residentHouse.setCommunityNo(house.getString("communityNo"));
        //小区名称
        residentHouse.setCommunityName(house.getString("communityName"));
        residentHouse.setCommunityViewName(house.getString("communityViewName"));
        //楼栋编号
        residentHouse.setBuildNo(house.getString("buildNo"));
        //楼栋名称
        residentHouse.setBuildName(house.getString("buildName"));

        residentHouse.setBuildViewName(house.getString("buildViewName"));

        //楼层名称
        residentHouse.setFloorName(house.getString("floorName"));

        //单元名称
        residentHouse.setUnitName(house.getString("unitName"));
        //房屋编号
        residentHouse.setHouseNo(house.getString("id"));
        //房屋名称
        residentHouse.setHouseName(house.getString("name"));

        residentHouse.setHouseViewName(house.getString("viewName"));
        //住户身份
        residentHouse.setType(resident.getType());

        //房屋类型 TODO 后续替换房屋中类型
        residentHouse.setHouseType(HouseType.HOUSE);

        //与业主的关系
        residentHouse.setRelationType(resident.getRelationType());

        //租赁开始时间
        residentHouse.setStartTime(resident.getStartTime());

        //租赁结束时间
        residentHouse.setEndTime(resident.getEndTime());

        //数据权限
        /*residentHouse.setDepartmentNo(house.getString("departmentNo"));
        residentHouse.setDepartmentName(house.getString("departmentName"));
        residentHouse.setDepartmentNos(JSONObject.parseArray(house.getJSONArray("departmentNos").toJSONString(), String.class));*/
        return residentHouse;
    }

    /**
     * 构建微信绑定的房屋信息
     *
     * @param residentHouseBindApply 微信房屋绑定申请
     * @return 微信绑定的房屋信息
     */
    public ResidentHouse buildResidentHouse(ResidentHouseBindApply residentHouseBindApply) {
        ResidentHouse residentHouse = Pool.newInstance(ResidentHouse.class);

        //真实姓名
        residentHouse.setRealname(residentHouseBindApply.getRealname());

        //手机号
        residentHouse.setMobile(residentHouseBindApply.getMobile());

        //头像
        residentHouse.setAvatar(residentHouseBindApply.getAvatar());

        //住户编号编号
        residentHouse.setResidentNo(residentHouseBindApply.getResidentNo());
        //小区编号
        residentHouse.setCommunityNo(residentHouseBindApply.getCommunityNo());
        //小区名称
        residentHouse.setCommunityName(residentHouseBindApply.getCommunityName());
        residentHouse.setCommunityViewName(residentHouseBindApply.getCommunityViewName());
        //楼栋编号
        residentHouse.setBuildNo(residentHouseBindApply.getBuildNo());
        //楼栋名称
        residentHouse.setBuildName(residentHouseBindApply.getBuildName());
        residentHouse.setBuildViewName(residentHouseBindApply.getBuildViewName());
        //楼层名称
        residentHouse.setFloorName(residentHouseBindApply.getFloorName());
        //单元名称
        residentHouse.setUnitName(residentHouseBindApply.getUnitName());
        //房屋编号
        residentHouse.setHouseNo(residentHouseBindApply.getHouseNo());
        //房屋名称
        residentHouse.setHouseName(residentHouseBindApply.getHouseName());
        residentHouse.setHouseViewName(residentHouseBindApply.getHouseViewName());
        //住户身份
        residentHouse.setType(residentHouseBindApply.getType());

        //与业主的关系
        residentHouse.setRelationType(residentHouseBindApply.getRelationType());

        //所属上级
        residentHouse.setPid(residentHouseBindApply.getPid());

        //所属上级名称
        residentHouse.setPname(residentHouseBindApply.getPname());

        //房屋类型
        residentHouse.setHouseType(residentHouseBindApply.getHouseType());

        //租赁开始时间
        residentHouse.setStartTime(residentHouseBindApply.getStartTime());

        //租赁结束时间
        residentHouse.setEndTime(residentHouseBindApply.getEndTime());

        residentHouse.setCompanyNo(residentHouseBindApply.getCompanyNo());

        //数据权限
       /* residentHouse.setDepartmentNo(residentHouseBindApply.getDepartmentNo());
        residentHouse.setDepartmentName(residentHouseBindApply.getDepartmentName());
        residentHouse.setDepartmentNos(residentHouseBindApply.getDepartmentNos());*/
        return residentHouse;
    }

    /**
     * 根据房屋编号集合获取房屋列表
     *
     * @param houseIds 房屋编号集合
     * @return 房屋列表
     * @throws Exception 异常
     */
    public JSONArray getHouseList(List<String> houseIds) throws Exception {
        JSONObject houseListResult = doveClient.post("/basic/house/service/list", (http) -> {
            JSONObject body = new JSONObject();
            body.put("id", houseIds);
            body.put("pageSize", Short.MAX_VALUE);
            http.setBody(body.toJSONString());
        });
        return houseListResult.getJSONArray("data");
    }


    /**
     * 根据店铺编号集合获取店铺列表
     *
     * @param shopIds 店铺编号集合
     * @return 店铺列表
     * @throws Exception 异常
     */
    public JSONArray getShopList(List<String> shopIds) throws Exception {
        JSONObject shopListResult = doveClient.post("/basic/shop/service/list", (http) -> {
            JSONObject body = new JSONObject();
            body.put("id", shopIds);
            body.put("pageSize", Short.MAX_VALUE);
            http.setBody(body.toJSONString());
        });
        return shopListResult.getJSONArray("data");
    }

    /**
     * 根据车位编号集合获取车位列表
     *
     * @param parkingIds 车位编号集合
     * @return 车位列表
     * @throws Exception 异常
     */
    public JSONArray getParkingList(List<String> parkingIds) throws Exception {
        JSONObject parkingListResult = doveClient.post("/basic/parking/service/list", (http) -> {
            JSONObject body = new JSONObject();
            body.put("id", parkingIds);
            body.put("pageSize", Short.MAX_VALUE);
            http.setBody(body.toJSONString());
        });
        return parkingListResult.getJSONArray("data");
    }

    /**
     * 设置住户房屋所属人相关信息
     *
     * @param resident      住户对象
     * @param residentHouse 住户房屋对象
     */
    public void buildPname(Resident resident, ResidentHouse residentHouse) {
        if (Objects.equal(resident.getType().getId(), ResidentType.OWNER.getId())) {
            residentHouse.setPid(Root.ROOT_ID);
            residentHouse.setPname(resident.getCompanyName());
        } else {
            //如果有租客和亲属所在房屋有业主，则设置业主相关信息
            ResidentHouse ownerHouse = getHouseOwner(residentHouse.getHouseNo());
            if (Objects.nonNull(ownerHouse)) {
                residentHouse.setPid(ownerHouse.getId());
                residentHouse.setPname(ownerHouse.getRealname());
            } else {
                residentHouse.setPid(Root.ROOT_ID);
                residentHouse.setPname(resident.getCompanyName());
            }

        }
    }

    /**
     * 更新商铺业主信息接口
     *
     * @param residentHouse 住户房屋信息
     * @throws Exception 异常
     */
    public void updateOwnerShopResult(ResidentHouse residentHouse) throws Exception {
        JSONObject updateShopResult = doveClient.post("/basic/shop/service/update", (http) -> {
            http.addHeader("companyNo", residentHouse.getCompanyNo());
            JSONObject body = new JSONObject();
            body.put("id", residentHouse.getHouseNo());
            body.put("ownerNo", residentHouse.getResidentNo());
            body.put("ownerName", residentHouse.getRealname());
            body.put("ownerMobile", residentHouse.getMobile());
            http.setBody(body.toJSONString());
        });
        if (updateShopResult.getIntValue("code") != 200) {
            logger.error("ResidentAssetsService.updateOwnerShopResult 回写商铺住户信息失败.后续修复数据一致性");
        }
    }

    /**
     * 更新商铺业主信息接口
     *
     * @param residentHouse 住户房屋信息
     * @throws Exception 异常
     */
    public void updateOwnerParkingResult(ResidentHouse residentHouse) throws Exception {
        JSONObject updateParkingResult = doveClient.post("/basic/parking/service/update", (http) -> {
            http.addHeader("companyNo", residentHouse.getCompanyNo());
            JSONObject body = new JSONObject();
            body.put("id", residentHouse.getHouseNo());
            body.put("ownerNo", residentHouse.getResidentNo());
            body.put("ownerName", residentHouse.getRealname());
            body.put("ownerMobile", residentHouse.getMobile());
            http.setBody(body.toJSONString());
        });
        if (updateParkingResult.getIntValue("code") != 200) {
            logger.error("ResidentAssetsService.updateOwnerParkingResult 回写车位住户信息失败.后续修复数据一致性");
        }
    }


    /**
     * 更新房屋业主信息接口
     *
     * @param residentHouse 住户房屋信息
     * @throws Exception 异常
     */
    private void updateOwnerHouseResult(ResidentHouse residentHouse) throws Exception {
        JSONObject updateHouseResult = doveClient.post("/basic/house/service/update", (http) -> {
            http.addHeader("companyNo", residentHouse.getCompanyNo());
            JSONObject body = new JSONObject();
            body.put("id", residentHouse.getHouseNo());
            body.put("ownerNo", residentHouse.getResidentNo());
            body.put("ownerName", residentHouse.getRealname());
            body.put("ownerMobile", residentHouse.getMobile());
            http.setBody(body.toJSONString());
        });
        if (updateHouseResult.getIntValue("code") != 200) {
            logger.error("ResidentServiceImpl.saveResident 回写房屋住户信息失败.后续修复数据一致性");
        }
    }

    public Resident updateResidentAssets(Resident resident, List<String> assetsIds, String assetsType) throws Exception {
        if (Objects.equal(resident.getType().getId(), ResidentType.OWNER.getId())) {
            //业主当前绑定房屋记录(住户,商户,车户批量新增模式下当前字段卫东),如果绑定业务有此字段则为单条新增模式
            String houseNo = resident.getHouseNo();
            if (Objects.equal(HouseType.HOUSE.getId(), assetsType)) {
                houseNo = resident.getHouseNo();
            } else if (Objects.equal(HouseType.SHOP.getId(), assetsType)) {
                houseNo = resident.getShopNo();
            } else if (Objects.equal(HouseType.PARKING.getId(), assetsType)) {
                houseNo = resident.getParkingNo();
            }
            //查询业主已绑定的资产记录(业主已认证的资产后台不能变更)
            List<ResidentHouse> ownerBindHouseList = jdbcSession.findArray(ResidentHouse.class)
                    .eq("houseType", assetsType)
                    .eq("residentNo", resident.getId())
                    .eq("type", ResidentType.OWNER)
                    .eq("deleted", false)
                    .eq("bindType", BindType.BIND).exe();
            //去除录入绑定房屋编号中已经绑定过的数据
            for (ResidentHouse ownerBindHouse : ownerBindHouseList) {
                assetsIds.remove(ownerBindHouse.getHouseNo());
            }
            if (Objects.isEmpty(assetsIds)) {
                return resident;
            }
            //查询业主未绑定的房产记录,解绑增量删除的业主数据
            List<ResidentHouse> noBindOwnerHouseList =new ArrayList<>();

            //如果业主是选中一条资产绑定记录进行操作则进行解绑,失效动作，在新增,否者直接新增
            if (Objects.nonEmpty(houseNo)) {//业主列表新增绑定当个资产
                //查询业主修改之前的当个房屋待绑绑定记录,解绑
                noBindOwnerHouseList = jdbcSession.findArray(ResidentHouse.class)
                        .eq("houseNo", houseNo)
                        .eq("houseType", assetsType)
                        .eq("residentNo", resident.getId())
                        .eq("type", ResidentType.OWNER)
                        .eq("deleted", false)
                        .eq("bindType", BindType.NO_BIND).exe();
            }else{
                //查询业主修改之前所有未绑定的房产记录,解绑增量删除的业主数据
                noBindOwnerHouseList = jdbcSession.findArray(ResidentHouse.class)
                        .eq("houseType", assetsType)
                        .eq("residentNo", resident.getId())
                        .eq("type", ResidentType.OWNER)
                        .eq("deleted", false)
                        .eq("bindType", BindType.NO_BIND).exe();
            }


            for (ResidentHouse noBindOwnerHouse : noBindOwnerHouseList) {
                //增量解绑当前住户未认证业主身份下面所有或单个未绑定资产,级联解除业主下面的租客和家属
                //传入的资产中不包含当前业主未绑定的记录则解绑
                if (!assetsIds.contains(noBindOwnerHouse.getHouseNo())) {
                    noBindOwnerHouse.setBindType(BindType.INVALID);
                    noBindOwnerHouse.setUnBindTime(LocalDateTime.now());
                    jdbcSession.updateById(noBindOwnerHouse);

                    //级联删除房屋业主信息为空
                    ResidentHouse removeHouseOwner = Pool.newInstance(ResidentHouse.class);
                    removeHouseOwner.setHouseNo(noBindOwnerHouse.getHouseNo());
                    removeHouseOwner.setResidentNo("");
                    removeHouseOwner.setRealname("");
                    removeHouseOwner.setMobile("");
                    if (Objects.equal(HouseType.HOUSE.getId(), assetsType)) {
                        updateOwnerHouseResult(removeHouseOwner);
                    } else if (Objects.equal(HouseType.SHOP.getId(), assetsType)) {
                        updateOwnerShopResult(removeHouseOwner);
                    } else if (Objects.equal(HouseType.PARKING.getId(), assetsType)) {
                        updateOwnerParkingResult(removeHouseOwner);
                    }

                    List<String> bindTypeList = new ArrayList<>();
                    bindTypeList.add(BindType.NO_BIND.getId());
                    bindTypeList.add(BindType.BIND.getId());
                    //解绑业主下面的租客和家属
                    List<ResidentHouse> noBindResidentHouseList = jdbcSession.findArray(ResidentHouse.class)
                            .eq("houseType", assetsType)
                            .eq("houseNo", noBindOwnerHouse.getHouseNo())
                            .in("bindType", bindTypeList)
                            .eq("deleted", false)
                            .exe();
                    for (ResidentHouse noBindResidentHouse : noBindResidentHouseList) {
                        noBindResidentHouse.setBindType(BindType.INVALID);
                        noBindResidentHouse.setUnBindTime(LocalDateTime.now());
                        jdbcSession.updateById(noBindResidentHouse);
                    }
                } else {
                    //当前绑定的房屋数据包含数据库中的业主房屋未绑定的数据
                    assetsIds.remove(noBindOwnerHouse.getHouseNo());
                }
            }
            if (Objects.isEmpty(assetsIds)) {
                return resident;
            }
            JSONArray houseList = null;
            if (Objects.equal(HouseType.HOUSE.getId(), assetsType)) {
                houseList = getHouseList(assetsIds);
            } else if (Objects.equal(HouseType.SHOP.getId(), assetsType)) {
                houseList = getShopList(assetsIds);
            } else if (Objects.equal(HouseType.PARKING.getId(), assetsType)) {
                houseList = getParkingList(assetsIds);
            }
            if (Objects.nonEmpty(houseList)) {
                for (Object houseObj : houseList) {
                    JSONObject house = (JSONObject) houseObj;
                    ResidentHouse residentHouse = buildResidentHouse(resident, house);
                    //完善住户绑定信息
                    if (Objects.equal(HouseType.HOUSE.getId(), assetsType)) {
                        residentHouse.setBuildNo(house.getString("buildNo"));
                        residentHouse.setBuildName(house.getString("buildName"));
                    } else if (Objects.equal(HouseType.SHOP.getId(), assetsType)) {
                        residentHouse.setBuildNo(house.getString("shopClassifyNo"));
                        residentHouse.setBuildName(house.getString("shopClassifyName"));
                    } else if (Objects.equal(HouseType.PARKING.getId(), assetsType)) {
                        residentHouse.setBuildNo(house.getString("yardNo"));
                        residentHouse.setBuildName(house.getString("yardName"));
                    }


                    //设置不同资产个性化字段
                    HouseType houseType = EnumUtil.getEnum(HouseType.class, assetsType);
                    residentHouse.setHouseType(houseType);


                    //设置房屋业主相关信息
                    buildPname(resident, residentHouse);
                    saveResidentHouse(residentHouse);
                    //更新相应资产业主信息
                    if (Objects.equal(HouseType.HOUSE.getId(), assetsType)) {
                        updateOwnerHouseResult(residentHouse);
                    } else if (Objects.equal(HouseType.SHOP.getId(), assetsType)) {
                        updateOwnerShopResult(residentHouse);
                    } else if (Objects.equal(HouseType.PARKING.getId(), assetsType)) {
                        updateOwnerParkingResult(residentHouse);
                    }

                }
            }
        } else {
            //租户或家属炒作的房屋记录
            String houseNo = resident.getHouseNo();
            if (Objects.equal(HouseType.HOUSE.getId(), assetsType)) {
                houseNo = resident.getHouseNo();
            } else if (Objects.equal(HouseType.SHOP.getId(), assetsType)) {
                houseNo = resident.getShopNo();
            } else if (Objects.equal(HouseType.PARKING.getId(), assetsType)) {
                houseNo = resident.getParkingNo();
            }
            //如果租户或家属是选中一条房屋绑定记录进行操作则进行解绑,失效动作，在新增,否者直接新增
            if (Objects.nonEmpty(houseNo)) {
                //去除录入绑定房屋编号中已经绑定过的数据
                List<ResidentHouse> bindHouseList = jdbcSession.findArray(ResidentHouse.class)
                        .eq("residentNo", resident.getId())
                        .eq("type", resident.getType())
                        .in("houseNo",houseNo)
                        .eq("deleted", false)
                        .eq("bindType", BindType.BIND).exe();
                //去除录入绑定房屋编号中已经绑定过的数据
                for (ResidentHouse bindHouse : bindHouseList) {
                    if (assetsIds.contains(bindHouse.getHouseNo())) {
                        assetsIds.remove(bindHouse.getHouseNo());
                        //与业主的关系
                        bindHouse.setRelationType(resident.getRelationType());
                        //租赁开始时间
                        bindHouse.setStartTime(resident.getStartTime());
                        //租赁结束时间
                        bindHouse.setEndTime(resident.getEndTime());
                        updateResidentHouse(bindHouse);
                    }
                }
                if (Objects.isEmpty(assetsIds)) {
                    return resident;
                }

                //解绑家属和租客(认证过的不能解绑)
                List<ResidentHouse> noBindOwnerHouseList = jdbcSession.findArray(ResidentHouse.class)
                        .eq("residentNo", resident.getId())
                        .eq("type", resident.getType())
                        .eq("houseNo",houseNo)
                        .eq("deleted", false)
                        .eq("bindType", BindType.NO_BIND).exe();
                for (ResidentHouse noBindOwnerHouse : noBindOwnerHouseList) {
                    if (!assetsIds.contains(noBindOwnerHouse.getHouseNo())) {
                        noBindOwnerHouse.setBindType(BindType.INVALID);
                        noBindOwnerHouse.setUnBindTime(LocalDateTime.now());
                        jdbcSession.updateById(noBindOwnerHouse);
                    } else {
                        //如果过滤后的未绑定数据在数据库已经存则删除这个房屋编号
                        assetsIds.remove(noBindOwnerHouse.getHouseNo());
                        //更新编辑住户房屋数据
                        //与业主的关系
                        noBindOwnerHouse.setRelationType(resident.getRelationType());
                        //租赁开始时间
                        noBindOwnerHouse.setStartTime(resident.getStartTime());
                        //租赁结束时间
                        noBindOwnerHouse.setEndTime(resident.getEndTime());
                        updateResidentHouse(noBindOwnerHouse);
                    }
                }

            }
            if (Objects.isEmpty(assetsIds)) {
                return resident;
            }
            JSONArray houseList = null;
            if (Objects.equal(HouseType.HOUSE.getId(), assetsType)) {
                houseList = getHouseList(assetsIds);
            } else if (Objects.equal(HouseType.SHOP.getId(), assetsType)) {
                houseList = getShopList(assetsIds);
            } else if (Objects.equal(HouseType.PARKING.getId(), assetsType)) {
                houseList = getParkingList(assetsIds);
            }
            if (Objects.nonEmpty(houseList)) {
                for (Object houseObj : houseList) {
                    JSONObject house = (JSONObject) houseObj;
                    ResidentHouse residentHouse = buildResidentHouse(resident, house);
                    //完善住户绑定信息
                    if (Objects.equal(HouseType.HOUSE.getId(), assetsType)) {
                        residentHouse.setBuildNo(house.getString("buildNo"));
                        residentHouse.setBuildName(house.getString("buildName"));
                    } else if (Objects.equal(HouseType.SHOP.getId(), assetsType)) {
                        residentHouse.setBuildNo(house.getString("shopClassifyNo"));
                        residentHouse.setBuildName(house.getString("shopClassifyName"));
                    } else if (Objects.equal(HouseType.PARKING.getId(), assetsType)) {
                        residentHouse.setBuildNo(house.getString("yardNo"));
                        residentHouse.setBuildName(house.getString("yardName"));
                    }
                    //设置不同资产个性化字段
                    HouseType houseType = EnumUtil.getEnum(HouseType.class, assetsType);
                    residentHouse.setHouseType(houseType);
                    buildPname(resident, residentHouse);
                    saveResidentHouse(residentHouse);
                }
            }
        }
        return resident;
    }

    /**
     * 校验住户房屋绑定唯一性
     * 一个房子只能有一个有效(待绑定,已绑定)业主记录
     * 一个房子只能只能有一条有效(待绑定,已绑定)租客或家属记录
     */
    private void checkResidentHouseUnique(ResidentHouse residentHouse) {
        if (Objects.isEmpty(residentHouse.getHouseNo())) {
            throw new RuntimeException("房屋编号不能为空.");
        }
        if (Objects.isEmpty(residentHouse.getResidentNo())) {
            throw new RuntimeException("住户编号不能为空.");
        }
        if (Objects.isNull(residentHouse.getType())) {
            throw new RuntimeException("住户类型不能为空.");
        }

        List<String> bindTypeList = new ArrayList<>();
        bindTypeList.add(BindType.NO_BIND.getId());
        bindTypeList.add(BindType.BIND.getId());
        FindArray<ResidentHouse> find = jdbcSession.findArray(ResidentHouse.class)
                .eq("houseNo", residentHouse.getHouseNo())
                .in("bindType", bindTypeList)
                .eq("deleted", false);
        if (Objects.equal(residentHouse.getType().getId(), ResidentType.OWNER.getId())) {
            find.eq("type", ResidentType.OWNER);
            find.eq("deleted", false);
            List<ResidentHouse> residentHouseList = find.exe();
            if (Objects.nonEmpty(residentHouseList)) {
                ResidentHouse ownerHouse = residentHouseList.get(0);
                if (Objects.equal(residentHouse.getResidentNo(), ownerHouse.getResidentNo())) {
                    throw new RuntimeException("不允许重复新增");
                } else {
                    throw new RuntimeException("当前房屋已经被其业主锁定");
                }
            }
        } else {
            find.eq("type", residentHouse.getType());
            find.eq("residentNo", residentHouse.getId());
            find.eq("deleted", false);
            List<ResidentHouse> residentHouseList = find.exe();
            if (Objects.nonEmpty(residentHouseList)) {
                throw new RuntimeException("不允许重复新增");
            }
        }
    }

    /**
     * 保存住户房屋
     *
     * @param residentHouse 住户房屋对象
     * @return 新增条数
     * @throws Exception 操作异常
     */

    private ResidentHouse saveResidentHouse(ResidentHouse residentHouse) throws Exception {
        if (logger.isDebugEnabled()) {
            logger.debug("parameter:" + residentHouse);
        }
        //重复数据唯一校验
        checkResidentHouseUnique(residentHouse);
        //保存住户房屋关系,逻辑删除相关历史数据
        if (Objects.nonEmpty(residentHouse.getResidentNo()) && Objects.nonEmpty(residentHouse.getHouseNo()) && Objects.nonNull(residentHouse.getType())) {
            List<ResidentHouse> residentHouseList = jdbcSession.findArray(ResidentHouse.class)
                    .eq("houseNo", residentHouse.getHouseNo())
                    .eq("residentNo", residentHouse.getResidentNo())
                    .eq("type", residentHouse.getType())
                    .eq("deleted", false)
                    .exe();
            for (ResidentHouse dbResidentHouse : residentHouseList) {
                dbResidentHouse.setDeleted(true);
                jdbcSession.updateById(dbResidentHouse);
            }
        }

        // 生成拥有者编号
        List<ResidentHouse> residentHouseList =
                jdbcSession.findArray(ResidentHouse.class)
                        .eq("communityNo", residentHouse.getCommunityNo())
                        .eq("residentNo", residentHouse.getResidentNo())
                        .eq("houseType", residentHouse.getHouseType().getId()).exe(false);
        if (Objects.nonEmpty(residentHouseList)) {
            for (ResidentHouse each : residentHouseList) {
                String ownerNo = each.getOwnerNo();
                if (!Objects.isBlank(ownerNo)) {
                    residentHouse.setOwnerNo(ownerNo);
                    break;
                }
            }
        }
        if (Objects.isBlank(residentHouse.getOwnerNo())) {
            SnowflakeIdUtils snowflakeIdUtils = new SnowflakeIdUtils(0);
            long id = snowflakeIdUtils.nextId();
            residentHouse.setOwnerNo(residentHouse.getHouseType().getCode() + id);
        }

        jdbcSession.insert(residentHouse);
        if (logger.isDebugEnabled()) {
            logger.debug("result:" + residentHouse);
        }
        return residentHouse;
    }

    public ResidentHouse updateResidentHouse(ResidentHouse residentHouse) throws Exception {
        if (logger.isDebugEnabled()) {
            logger.debug("parameter:" + residentHouse);
        }
        jdbcSession.updateById(residentHouse);
        if (logger.isDebugEnabled()) {
            logger.debug("result:" + residentHouse);
        }
        return residentHouse;
    }


    /**
     * 绑定住户业主身份资产信息
     * 1.校验资产是否被绑定(自己或他人)
     * 2.新增认证资产绑定记录
     * 3.会写业主信息到具体的资产上面去
     * @param jsonObject
     * @return
     * @throws Exception
     */
    @ReqMapping("/bind")
    public Object bindResidentOwnerAssets(JSONObject jsonObject) throws Exception {
        //资产编号
        String assetsNo=jsonObject.getString("assetsNo");
        //资产类型
        String assetsType=jsonObject.getString("assetsType");
        //住户编号
        String residentNo=jsonObject.getString("residentNo");
        String companyName=jsonObject.getString("companyName");
        String companyNo=jsonObject.getString("companyNo");

        Resident resident=jdbcSession.findById(Resident.class,residentNo);
        resident.setCompanyName(companyName);
        resident.setCompanyNo(companyNo);
        List<ResidentHouse> residentAssetsList=jdbcSession.findArray(ResidentHouse.class)
                .eq("houseType", assetsType)
                .eq("houseNo",assetsNo)
                .eq("type", ResidentType.OWNER.getId())
                .eq("deleted", false)
                .exe();


        if(Objects.nonEmpty(residentAssetsList)){
            ResidentHouse ownerHouse = residentAssetsList.get(0);
            if (Objects.equal(residentNo, ownerHouse.getResidentNo())) {
                throw new RuntimeException("不允许重复新增");
            } else {
                throw new RuntimeException("当前房屋已经被其业主锁定");
            }
        }

        if (Objects.equal(HouseType.HOUSE.getId(), assetsType)) {
            List<String> houseIds=new ArrayList<>();
            houseIds.add(assetsNo);
            JSONArray houseList =getHouseList(houseIds);
            if (Objects.nonEmpty(houseList)) {
                for (Object houseObj : houseList) {
                    JSONObject house = (JSONObject) houseObj;
                    ResidentHouse residentHouse =buildResidentHouse(resident, house);
                    //设置房屋业主相关信息
                    residentHouse.setPid(Root.ROOT_ID);
                    residentHouse.setPname(companyName);
                    buildPname(resident, residentHouse);
                    residentHouse.setBindType(BindType.BIND);
                    residentHouse.setBindTime(LocalDateTime.now());
                    saveResidentHouse(residentHouse);
                    //如果业主绑定房屋会写房屋信息
                    updateOwnerHouseResult(residentHouse);
                }
            }
        } else if (Objects.equal(HouseType.SHOP.getId(), assetsType)) {
            List<String> shopIds=new ArrayList<>();
            shopIds.add(assetsNo);
            JSONArray shopList =getShopList(shopIds);
            if (Objects.nonEmpty(shopList)) {
                for (Object shopObj : shopList) {
                    JSONObject shop = (JSONObject) shopObj;
                    ResidentHouse residentHouse =buildResidentHouse(resident, shop);
                    residentHouse.setBuildNo(shop.getString("shopClassifyNo"));
                    residentHouse.setBuildName(shop.getString("shopClassifyName"));
                    residentHouse.setHouseType(HouseType.SHOP);
                    //设置房屋业主相关信息
                    buildPname(resident, residentHouse);

                    saveResidentHouse(residentHouse);

                    residentHouse.setBindType(BindType.BIND);
                    residentHouse.setBindTime(LocalDateTime.now());
                    //如果业主绑定房屋会写房屋信息
                    updateOwnerShopResult(residentHouse);

                }
            }

        } else if (Objects.equal(HouseType.PARKING.getId(), assetsType)) {
            List<String> parkingIds=new ArrayList<>();
            parkingIds.add(assetsNo);
            JSONArray parkingList =getParkingList(parkingIds);
            if (Objects.nonEmpty(parkingList)) {
                for (Object parkingObj : parkingList) {
                    JSONObject parking = (JSONObject) parkingObj;
                    ResidentHouse residentHouse =buildResidentHouse(resident, parking);
                    residentHouse.setBuildNo(parking.getString("yardNo"));
                    residentHouse.setBuildName(parking.getString("yardName"));
                    residentHouse.setHouseType(HouseType.PARKING);
                    //设置房屋业主相关信息
                    buildPname(resident, residentHouse);

                    saveResidentHouse(residentHouse);
                    residentHouse.setBindType(BindType.BIND);
                    residentHouse.setBindTime(LocalDateTime.now());
                    //如果业主绑定房屋会写房屋信息
                    updateOwnerParkingResult(residentHouse);
                }
            }

        }
        return Result.success();
    }

}
